package com.xinshujia.config.authentication.provider;

import com.xinshujia.config.authentication.service.MyPhoneDetailsService;
import com.xinshujia.config.authentication.service.MyUsernamePasswordDetailsService;
import com.xinshujia.config.authentication.token.MyPhoneAuthenticationToken;
import com.xinshujia.entity.UserEntity;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * *************************************
 * *   @author: 野狼上校               **
 * *   @since: 2024-07-16 13:30       **
 * *   @version: 1.0                  **
 * *************************************
 * <p>
 *     手机号码登录 认证处理器
 */
@Component
public class MyPhoneAuthenticationProvider  implements AuthenticationProvider {

 private final MyPhoneDetailsService myPhoneDetailsService;

    public MyPhoneAuthenticationProvider(MyPhoneDetailsService myPhoneDetailsService) {
        this.myPhoneDetailsService = myPhoneDetailsService;
    }


    @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  // 1. 获取用户输入的信息
  MyPhoneAuthenticationToken myPhoneAuthenticationToken = (MyPhoneAuthenticationToken) authentication;
  String phone = (String) myPhoneAuthenticationToken.getPrincipal();
  String password = (String) myPhoneAuthenticationToken.getCredentials();

  // 2. 根据phone从数据库中查询用户信息
  UserEntity userEntity = (UserEntity) myPhoneDetailsService.loadUserByUsername(phone);
  if (null == userEntity) {
   throw new BadCredentialsException("账号不存在");
  }
  // 3. 验证密码是否正确(使用DelegatingPasswordEncode加密方案)
  PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
  boolean matches = delegatingPasswordEncoder.matches(authentication.getCredentials().toString(), userEntity.getPassword());
  if (!matches) {
   throw new BadCredentialsException("密码不正确");
  }
  // 4. 把用户信息封装到PhoneAuthenticationToken中
  MyPhoneAuthenticationToken phoneAuthenticationTokenFull = new MyPhoneAuthenticationToken(userEntity, password, userEntity.getAuthorities());
  phoneAuthenticationTokenFull.setDetails(myPhoneAuthenticationToken.getDetails());
  return phoneAuthenticationTokenFull;
 }

 @Override
 public boolean supports(Class<?> authentication) {
  return MyPhoneAuthenticationToken.class.isAssignableFrom(authentication);
 }
}